from fastapi import FastAPI, Request, Response
import uvicorn
from fastapi.responses import RedirectResponse, StreamingResponse, FileResponse
import orjson

app = FastAPI()


@app.get("/")
async def view_func(request: Request):
    return {"name": "古明地觉"}


#
# @app.middleware("http")
# async def middleware(request: Request, call_next):
#     """
#     定义一个协程函数，然后使用 @app.middleware("http") 装饰，即可得到中间件
#     """
#     # 请求到来时会先经过这里的中间件
#     if request.headers.get("ping", "") != "pong":
#         response = Response(content=orjson.dumps({"error": "请求头中缺少指定字段"}),
#                             media_type="application/json",
#                             status_code=404)
#         # 当请求头中缺少 "ping": "pong"，在中间件这一步就直接返回了，就不会再往下走了
#         # 所以此时就相当于实现了一个拦截器
#         return response
#     # 然后，如果条件满足，则执行 await call_next(request)，关键是这里的 call_next
#     # 如果该中间件后面还有中间件，那么 call_next 就是下一个中间件；如果没有，那么 call_next 就是对应的视图函数
#     # 这里显然是视图函数，因此执行之后会拿到视图函数返回的 Response 对象
#     # 所以我们看到在 FastAPI 中，请求中间件和响应中间件合在一起了
#     response: Response = await call_next(request)
#     # 这里我们在设置一个响应头
#     response.headers["status"] = "success"
#     return response


@app.get("/index/")
async def index():
    return RedirectResponse("https://www.bilibili.com")


async def some_video():
    for i in range(2, 6):
        with open(f"main{i}.py", "r", encoding='utf-8') as fp:
            x = fp.read()
            yield x.encode('utf-8')
        # yield open(f"main{i}.py", "rb")


@app.get("/index2")
async def index():
    return StreamingResponse(some_video())


@app.get("/index3")
async def index():
    return StreamingResponse(open("main.py", encoding="utf-8"))


@app.get("/index4")
async def index():
    # filename 如果给出，它将包含在响应的 Content-Disposition 中。
    return FileResponse("main.py", filename="这不是main.py")


if __name__ == "__main__":
    uvicorn.run("main6:app", host="0.0.0.0", port=5555)
